package com.baidu.iit.pxp.parser.factory;

import com.baidu.iit.pvm.ActivityIllegalArgumentException;
import com.baidu.iit.pvm.delegate.ExecutionListener;
import com.baidu.iit.pvm.runtime.Execution;
import com.baidu.iit.pvm.runtime.ProcessInstance;
import com.baidu.iit.pxp.delegate.ClassDelegate;
import com.baidu.iit.pxp.entity.ProcessDefinition;
import com.baidu.iit.pxp.listener.*;
import com.baidu.iit.pxp.model.ActivitiListener;
import com.baidu.iit.pxp.model.EventListener;
import com.baidu.iit.pxp.model.Task;

import java.util.HashMap;
import java.util.Map;

/**
 * User: huangweili
 * Date: 14-4-24
 * Time: 下午6:47
 */
public class DefaultListenerFactory extends AbstractBehaviorFactory implements ListenerFactory {

    public static final Map<String, Class<?>> ENTITY_MAPPING = new HashMap<String, Class<?>>();
    static {
        ENTITY_MAPPING.put("execution", Execution.class);
        ENTITY_MAPPING.put("process-definition", ProcessDefinition.class);
        ENTITY_MAPPING.put("process-instance", ProcessInstance.class);
        ENTITY_MAPPING.put("task", Task.class);
    }

    public TaskListener createClassDelegateTaskListener(ActivitiListener activitiListener) {
        return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()));
    }

    public TaskListener createExpressionTaskListener(ActivitiListener activitiListener) {
        return new ExpressionTaskListener(expressionManager.createExpression(activitiListener.getImplementation()));
    }

    public TaskListener createDelegateExpressionTaskListener(ActivitiListener activitiListener) {
        return new DelegateExpressionTaskListener(expressionManager.createExpression(activitiListener.getImplementation()),
                createFieldDeclarations(activitiListener.getFieldExtensions()));
    }

    public ExecutionListener createClassDelegateExecutionListener(ActivitiListener activitiListener) {
        return new ClassDelegate(activitiListener.getImplementation(), createFieldDeclarations(activitiListener.getFieldExtensions()));
    }

    public ExecutionListener createExpressionExecutionListener(ActivitiListener activitiListener) {
        return new ExpressionExecutionListener(expressionManager.createExpression(activitiListener.getImplementation()));
    }

    public ExecutionListener createDelegateExpressionExecutionListener(ActivitiListener activitiListener) {
        return new DelegateExpressionExecutionListener(expressionManager.createExpression(activitiListener.getImplementation()),
                createFieldDeclarations(activitiListener.getFieldExtensions()));
    }

    @Override
    public ActivityEventListener createClassDelegateEventListener(EventListener eventListener) {
        return new DelegateActivitiEventListener(eventListener.getImplementation(), getEntityType(eventListener.getEntityType()));
    }

    @Override
    public ActivityEventListener createDelegateExpressionEventListener(EventListener eventListener) {
        return new DelegateExpressionActivitiEventListener(expressionManager.createExpression(
                eventListener.getImplementation()), getEntityType(eventListener.getEntityType()));
    }



    protected Class<?> getEntityType(String entityType) {
        if(entityType != null) {
            Class<?> entityClass = ENTITY_MAPPING.get(entityType.trim());
            if(entityClass == null) {
                throw new ActivityIllegalArgumentException("Unsupported entity-type for an ActivitiEventListener: " + entityType);
            }
            return entityClass;
        }
        return null;
    }
}
